package demo2;

/**
 * CRC工具类：负责CRC校验码的生成和校验
 * 核心原理：通过模2除法计算数据帧的校验码，确保数据传输正确性
 */
public class CRC {
    /**
     * CRC校验核心方法
     *
     * @param data      原始二进制数据（如字符转换的8位二进制）
     * @param generator 生成多项式（此处固定为"1011"）
     * @param crcCode   若为null：生成校验码；若不为null：校验该码是否正确
     * @return 生成模式返回校验码；校验模式返回空（通过）或非空余数（失败）
     */
    public static String crcCheck(String data, String generator, String crcCode) {
        int generatorLen = generator.length();
        // 生成校验码时，数据后补(生成多项式长度-1)个0（用于模2除法）
        String temp = (crcCode == null) ? data + "0".repeat(generatorLen - 1) : data + crcCode;
        char[] tempArr = temp.toCharArray();
        char[] generatorArr = generator.toCharArray();

        // 模2除法核心：逐位与生成多项式异或
        for (int i = 0; i <= tempArr.length - generatorLen; i++) {
            if (tempArr[i] == '1') { // 当前位为1时，用生成多项式异或
                for (int j = 0; j < generatorLen; j++) {
                    // 异或逻辑：相同为0，不同为1
                    tempArr[i + j] = (tempArr[i + j] == generatorArr[j]) ? '0' : '1';
                }
            }
        }

        // 提取余数（即CRC校验码，长度为生成多项式长度-1）
        StringBuilder remainder = new StringBuilder();
        for (int i = tempArr.length - generatorLen + 1; i < tempArr.length; i++) {
            remainder.append(tempArr[i]);
        }

        // 全0则通过（返回空），否则返回余数
        return (crcCode == null) ? remainder.toString() : (remainder.toString().matches("0+") ? "" : remainder.toString());
    }
}